package com.iqiyi.pps.epg.core.utils;


import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.iqiyi.kiwi.utils.EncodeUtils;
import org.apache.commons.lang.StringUtils;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author fangying
 * @version 12-3-8 - 下午5:44
 */
public class StringUtil {
    public static Random random = new Random();

    /**
     * 获取当前时间字符串
     *
     * @return 当前时间字符串
     */
    public static String getStringTime() {
        Date date = new Date();//获取当前系统时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSSS");//设置格式化格式
        return sdf.format(date);//返回格式化后的时间
    }

    public static String getStringDate(String time, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);//设置格式化格式
            Timestamp t = new Timestamp(sdf.parse(time).getTime());//返回格式化后的时间
            return sdf.format(t.getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getStringTime(String format) {
        Date date = new Date();//获取当前系统时间
        SimpleDateFormat sdf = new SimpleDateFormat(format);//设置格式化格式
        return sdf.format(date);//返回格式化后的时间
    }

    public static String getStringTime(String format, Timestamp time) {
        if (time == null)
            return "";
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time.getTime());

        SimpleDateFormat sdf = new SimpleDateFormat(format);//设置格式化格式
        return sdf.format(calendar.getTime());//返回格式化后的时间
    }

    /**
     * 按指定格式把字符串解析为时间戳
     *
     * @param datetime 时间字符串
     * @param format   时间格式
     * @return 时间戳
     */
    public static Timestamp parseDatetime(String datetime, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);//设置格式化格式
            return new Timestamp(sdf.parse(datetime).getTime());//返回格式化后的时间
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 把HH:mm:ss格式的字符串解析为毫秒
     *
     * @param time 时间字符串
     * @return 毫秒
     */
    public static Long parseTime(String time) {
        Long ret = 0L;
        try {
            String[] p = time.split(":");
            ret = (Long.valueOf(p[0]) * 60 * 60 + Long.valueOf(p[1]) * 60 + Long.valueOf(p[2])) * 1000;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret;
    }

    /**
     * 把毫秒解析为HH:mm:ss格式的字符串
     *
     * @param timeMillis 毫秒
     * @return HH:mm:ss
     */
    public static String toTime(Long timeMillis) {
        Long total = timeMillis / 1000;
        Long h = total / 3600;
        Long m = (total % 3600) / 60;
        Long s = total % 60;

        String hh = "00";
        String mm = "00";
        String ss = "00";
        if (h < 10 && h > 0) {
            hh = "0" + h;
        } else if (h >= 10) {
            hh = h + "";
        }
        if (m < 10 && m > 0) {
            mm = "0" + m;
        } else if (m >= 10) {
            mm = m + "";
        }
        if (s < 10 && s > 0) {
            ss = "0" + s;
        } else if (s >= 10) {
            ss = s + "";
        }
        return hh + ":" + mm + ":" + ss;
    }

    public static String toTimeBySec(Long timeSec) {
        Long h = timeSec / 3600;
        Long m = (timeSec % 3600) / 60;
        Long s = timeSec % 60;

        String hh = "00";
        String mm = "00";
        String ss = "00";
        if (h < 10 && h > 0) {
            hh = "0" + h;
        } else if (h >= 10) {
            hh = h + "";
        }
        if (m < 10 && m > 0) {
            mm = "0" + m;
        } else if (m >= 10) {
            mm = m + "";
        }
        if (s < 10 && s > 0) {
            ss = "0" + s;
        } else if (s >= 10) {
            ss = s + "";
        }
        return hh + ":" + mm + ":" + ss;
    }

    /**
     * 按yyyy-MM-dd HH:mm:ss格式把字符串解析为时间戳
     *
     * @param datetime 时间字符串
     * @return 时间戳
     */
    public static Timestamp parseDatetime(String datetime) {
        return parseDatetime(datetime, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 取得日期格式文件路径 例 2012/09/03
     *
     * @param time
     * @return
     */
    public static String getDateFormatPath(long time) {
        return getStringTime("/yyyy/MM/dd", new Timestamp(time));
    }

    /**
     * 取得日期格式文件路径 例 2012/09/03
     *
     * @return
     */
    public static String getDateFormatPath() {
        return getDateFormatPath(new Date().getTime());
    }

    /**
     * 生成订单号
     *
     * @return 订单号
     */
    public static String createOrderId() {
        StringBuffer sb = new StringBuffer();//定义字符串对象
        sb.append(getStringTime());//向字符串对象中添加当前系统时间
        for (int i = 0; i < 3; i++) {//随机生成3位数
            sb.append(random.nextInt(9));//将随机生成的数字添加到字符串对象中
        }
        return sb.toString();//返回字符串
    }

    public static String createUniqueCode() {
        StringBuffer sb = new StringBuffer();//定义字符串对象
        sb.append(getStringTime());//向字符串对象中添加当前系统时间
        for (int i = 0; i < 3; i++) {//随机生成3位数
            sb.append(random.nextInt(9));//将随机生成的数字添加到字符串对象中
        }
        return sb.toString();//返回字符串
    }

    public static String formatPrice(Integer price) {
        StringBuffer bf = new StringBuffer("￥");
        Integer yuan = price / 100;
        Integer fen = price % 100;
        bf.append(yuan + "." + fen);

        return bf.toString();
    }

    /* 过滤网页文本
    * @param html 要过滤的网页文本
    * @return 过滤后的网页文本
    */
    public static String filterHtml(String html) {
        html = html.replaceAll("&", "&amp;");
        html = html.replaceAll("<", "&lt;");
        html = html.replaceAll(">", "&gt;");
        html = html.replaceAll(" ", "&nbsp;");
        html = html.replaceAll("'", "&#92;&#39;");
        html = html.replaceAll("\"", "&quot;");
        html = html.replaceAll("\n", "<br/>");
        return html;
    }

    /**
     * 验证手机电话号码
     *
     * @param phone
     * @return
     */
    public static boolean validateMoblie(String phone) {
        boolean rs = false;
        if (phone.length() != 11) return rs;
        String expression = "^(10[0-9]|13[0-9]|15[0-9]|18[0-9]|147)\\d{4,8}$";
        Pattern p = Pattern.compile(expression); // 正则表达式
        Matcher m = p.matcher(phone); // 操作的字符串
        rs = m.matches();
        return rs;
    }

    /**
     * 手机所属运营商，-1表示未知
     *
     * @param phone
     * @return
     */
    public static int moblieBelong(String phone) {
        int rs = -1;
        if (phone.length() != 11) return rs;
        String expression_cmmb = "^(13[4-9]|147|15[0|1|2|7|8|9]|18[2|3|7|8])\\d{4,8}$";
        String expression_unicom = "^(13[0-2]|15[5|6]|18[5|6])\\d{4,8}$";
        String expression_telecom = "^(10[2|5|6|7|8|9]|133|153|18[0|9])\\d{4,8}$";
        Pattern p = Pattern.compile(expression_cmmb); // 正则表达式
        Matcher m = p.matcher(phone); // 操作的字符串
        if (m.matches())
            return 1;    //移动
        p = Pattern.compile(expression_unicom);
        m = p.matcher(phone);
        if (m.matches())
            return 2;    //联通
        p = Pattern.compile(expression_telecom);
        m = p.matcher(phone);
        if (m.matches())
            return 3;    //电信
        return rs;
    }

    /**
     * 隐藏手机号中间4位
     *
     * @param phone
     * @return
     */
    public static String hideMobile(String phone) {
        if (!validateMoblie(phone)) {
            return phone;
        }
        phone = phone.substring(0, 3) + "****" + phone.substring(7, 11);
        return phone;
    }

    public static boolean validateEmail(String email) {
        String check = "^([a-z0-9A-Z_\\-|\\.])+@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
        Pattern regex = Pattern.compile(check);
        Matcher matcher = regex.matcher(email);
        boolean isMatched = matcher.matches();
        return isMatched;
    }

    public static boolean validateUrl(String url) {
        String check = "^((https|http)?://)"
                + "(([0-9].)[0-9]" // IP形式的URL- 199.194.52.184
                + "|" // 允许IP和DOMAIN（域名）
                + "([0-9a-z_!~*'()-]+.)*" // 域名-
                + "([0-9a-z][0-9a-z-])?[0-9a-z]." // 二级域名
                + "[a-z])" // first level domain- .com or .museum
                + "(:[0-9])?" // 端口- :80
                + "((/?)|" // a slash isn't required if there is no file name
                + "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$";
        Pattern regex = Pattern.compile(check);
        Matcher matcher = regex.matcher(url);
        boolean isMatched = matcher.matches();
        return isMatched;
    }

    /**
     * 获取异常的堆栈输出
     *
     * @param t
     * @return
     */
    public static String getStackTrace(Throwable t) {
        StringWriter stringWritter = new StringWriter();
        PrintWriter printWritter = new PrintWriter(stringWritter, true);
        t.printStackTrace(printWritter);
        printWritter.flush();
        stringWritter.flush();
        return stringWritter.toString();
    }

    /**
     * 把map中的null转换空字符串
     *
     * @param map
     * @return
     */
    public static Map<String, String> nullToEmptyString(Map<String, String> map) {
        List keys = new ArrayList(map.keySet());
        Map<String, String> sArrayNew = new HashMap<String, String>();

        for (int i = 0; i < keys.size(); i++) {
            String key = (String) keys.get(i);
            String value = (String) map.get(key);
            if (value == null) {
                value = "";
            }
            sArrayNew.put(key, value);
        }
        return sArrayNew;
    }

    public static String nullToEmptyString(String oldValue) {
        if (oldValue == null) {
            return "";
        }
        return oldValue;
    }

    /**
     * 将字符串转换为整型数返回
     *
     * @param str
     * @return
     */
    public static Integer toInteger(String str) {
        try {
            if (str == null || str.equals("")) {
                return new Integer(-1);
            } else {
                return Integer.parseInt(str);
            }
        } catch (Exception e) {
            System.out.println("str " + str + " toInteger error!" + e.getMessage());
        }
        return null;

    }

    /**
     * 将字符串转为Long型
     *
     * @param string
     * @param def
     * @return
     */
    public static Long toLong(String string, Long def) {
        try {
            if (string == null || string.equals("") || string.equals("null")) {
                return def;
            } else {
                return Long.parseLong(string);
            }
        } catch (Exception e) {
            System.out.println("string " + string + " toLong error!" + e.getMessage());
        }
        return def;
    }

    /**
     * 将字符串按照指定的符号分割，并返回一个Long数组
     *
     * @param idstr
     * @param s
     * @return
     */
    public static Long[] spiltToLongArray(String idstr, String s) {
        if (idstr == null || idstr.length() <= 0) return null;
        if (s == null || s.equals("")) return null;
        String str[] = idstr.split(s);
        Long[] result = new Long[str.length];

        for (int i = 0; i < str.length; i++) {
            Long d;
            try {
                d = Long.parseLong(str[i]);
            } catch (Exception e) {
                d = null;
            }
            result[i] = d;
        }
        return result;
    }

    public static String[] spiltToStrings(String str, String s) {
        if (str == null || str.length() <= 0) {
            return null;
        }
        if (s == null || s.length() <= 0) {
            return null;
        }
        String tmpArray[] = str.split(s);
        return tmpArray;
    }

    public static String replaceAll(String value, String oldStr, String newStr) {
        if (value == null || value.length() <= 0) {
            return value;
        }
        if (oldStr == null || oldStr.length() == 0 || newStr == null || newStr.length() == 0) {
            return value;
        }

        value = value.replace(oldStr, newStr);
        return value;
    }

    /**
     * 处理html静态页面输出的字符串
     *
     * @param str
     * @return
     */
    public static String toHtmlOut(String str) {
        if (str == null || str.length() == 0) {
            return "";
        }
        str = str.replace("\"", "'");
        return str;
    }

    public static Integer[] spiltToIntegerArray(String str, String split) {
        if (str == null || str.length() <= 0) return null;
        if (split == null || split.equals("")) return null;
        String tmp[] = str.split(split);
        Integer[] result = new Integer[tmp.length];

        for (int i = 0; i < tmp.length; i++) {
            Integer d;
            try {
                d = Integer.parseInt(tmp[i].trim());
            } catch (Exception e) {
                d = null;
            }
            result[i] = d;
        }
        return result;
    }

    /**
     * 生成唯一视频VID
     *
     * @return
     */
    public static String generateVid() {
        return EncodeUtils.MD5(StringUtil.createUniqueCode(), "UTF-8");
    }

    /**
     * 换算文件大小
     *
     * @return
     */
    public static String getFormatSize(double size) {
        double kiloByte = size / 1024;
        if (kiloByte < 1) {
            return size + "Byte(s)";
        }

        double megaByte = kiloByte / 1024;
        if (megaByte < 1) {
            BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
            return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
        }

        double gigaByte = megaByte / 1024;
        if (gigaByte < 1) {
            BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
            return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
        }

        double teraBytes = gigaByte / 1024;
        if (teraBytes < 1) {
            BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
        }
        BigDecimal result4 = new BigDecimal(teraBytes);
        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
    }

    public static Integer toInteger(String str, int def) {
        Integer result = toInteger(str);
        return result == null ? def : result;
    }

    /**
     * 中文截字
     *
     * @param str 原始字符
     * @param len 截字长度
     * @return
     */
    public static String getLimitLengthString(String str, int len) {
        try {
            int counterOfDoubleByte = 0;
            byte[] b = str.getBytes("gb2312");
            if (b.length <= len)
                return str;
            for (int i = 0; i < len; i++) {
                if (b[i] < 0)
                    counterOfDoubleByte++;
            }

            if (counterOfDoubleByte % 2 == 0)
                return new String(b, 0, len, "gb2312");
            else
                return new String(b, 0, len - 1, "gb2312");
        } catch (Exception ex) {
            ex.printStackTrace();
            return "";
        }
    }

    /**
     * 转移json串中的特殊字符
     *
     * @param s
     * @return
     */
    public static String string2Json(String s) {
        StringBuffer sb = new StringBuffer();
        if (s != null && s.length() > 0) {
            for (int i = 0; i < s.length(); i++) {
                char c = s.charAt(i);
                switch (c) {
                    case '\"':
                        sb.append("\\\"");
                        break;
                    case '\\':
                        sb.append("\\\\");
                        break;
                    case '/':
                        sb.append("\\/");
                        break;
                    case '\b':
                        sb.append("\\b");
                        break;
                    case '\f':
                        sb.append("\\f");
                        break;
                    case '\n':
                        sb.append("\\n");
                        break;
                    case '\r':
                        sb.append("\\r");
                        break;
                    case '\t':
                        sb.append("\\t");
                        break;
                    default:
                        sb.append(c);
                }
            }
        }

        return sb.toString();
    }

    public static String getDayBefore(String specifiedDay) {
        Calendar c = Calendar.getInstance();
        Date date = null;
        try {
            date = new SimpleDateFormat("yyyy-MM-dd").parse(specifiedDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day - 1);

        String dayBefore = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
        return dayBefore;
    }

    public static boolean isNeedRetry(String needCodes, String code) {
        if (StringUtils.isBlank(needCodes) || StringUtils.isBlank(code) || "NONE".equalsIgnoreCase(needCodes)) {
            return false;
        }
        if ("ALL".equalsIgnoreCase(needCodes)) {
            return true;
        }
        if (code.indexOf("|") >= 0) {
            code = code.substring(code.lastIndexOf("|"));
        }
        if (needCodes.indexOf("[" + code + "]") >= 0) {
            return true;
        }
        return false;
    }

    public static String toString(List<Long> ids, String str) {
        if (ids == null || ids.size() <= 0) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (Long value : ids) {
            sb.append(value + str);
        }
        if (sb.lastIndexOf(str) > 0) {
            sb.delete(sb.lastIndexOf(str), sb.lastIndexOf(str) + str.length());
        }
        return sb.toString();
    }

    public static List<Long> getListFromJsonString(String json) {
        Gson gson = new Gson();
        return gson.fromJson(json, new TypeToken<List<Long>>() {
        }.getType());
    }

    public static String mergeToString(String[] str, String s) {
        if (str == null || str.length <= 0) {
            return null;
        }
        if (s == null || s.length() <= 0) {
            return null;
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < str.length; i++) {
            sb.append(str[i]).append(s);
        }
        return sb.toString().substring(0, sb.toString().lastIndexOf(s));
    }

    /**
     * 字符串匹配百分比（顺序）
     *
     * @param src
     * @param dest
     * @param charset
     * @return
     */
    public static int seqAlikePercent(String src, String dest, String charset) {
        int length = 0;         //总长
        int matches = 0;        //匹配正确的数量

        if (src == null && dest == null) {
            return 100;
        } else if (src == null || dest == null) {
            return 0;
        } else {
            byte[] srcBytes = null;
            byte[] destBytes = null;
            try {
                if (charset == null) {
                    srcBytes = src.getBytes();
                    destBytes = dest.getBytes();
                } else {
                    srcBytes = src.getBytes(charset);
                    destBytes = dest.getBytes(charset);
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return -1;
            }
            int srcLength = srcBytes.length;
            int destLength = destBytes.length;

            if (srcLength == 0 && destLength == 0) {
                return 100;
            } else if (srcLength == 0 || destLength == 0) {
                return 0;
            }
            if (srcLength <= destLength) {
                length = srcLength;
            } else {
                length = destLength;
            }

            for (int item = 0; item < length; item++) {
                byte srcByte = srcBytes[item];
                byte destByte = destBytes[item];
                if (srcByte == destByte) {
                    matches = matches + 1;
                } else {
                }
            }

            double rate = (double) matches / (double) length * 100;
            BigDecimal b = new BigDecimal(rate);
            int alikePercent = b.setScale(0, BigDecimal.ROUND_HALF_UP).intValue();

            return alikePercent;
        }
    }

    /**
     * 字符串匹配百分比（交集）
     *
     * @param src
     * @param dest
     * @return
     */
    public static int alikePercent(String src, String dest) {
        List<Integer> list = StringUtil.alikePercentList(src, dest);
        return list.get(0);
    }

    public static List<Integer> alikePercentList(String src, String dest) {
        //(百分比，正确的数量，错误的数量)
        int length = 0;         //总长
        int matches = 0;        //匹配正确的数量

        if (src == null && dest == null) {
            return new ArrayList<Integer>(){{add(100); add(0); add(0);}};
        } else if (src == null || dest == null) {
            return new ArrayList<Integer>(){{add(0); add(0); add(0);}};
        }
        int srcLength = src.length();
        int destLength = dest.length();
        if (srcLength == 0 && destLength == 0) {
            return new ArrayList<Integer>(){{add(100); add(0); add(0);}};
        } else if (srcLength == 0 || destLength == 0) {
            return new ArrayList<Integer>(){{add(0); add(0); add(0);}};
        }

        char[] srcChar = src.toCharArray();
        char[] destChar = dest.toCharArray();

        List<Character> destList = new ArrayList<Character>();
        for (int item = 0; item < destChar.length; item++) {
            destList.add(destChar[item]);
        }

        List<Character> srcList = new ArrayList<Character>();
        for (int item = 0; item < srcChar.length; item++) {
            srcList.add(srcChar[item]);
        }

        length = destList.size();
        for (Iterator destIt = destList.iterator(); destIt.hasNext(); ) {
            Character destTemp = (Character) destIt.next();
            for (Iterator srcIt = srcList.iterator(); srcIt.hasNext(); ) {
                Character srcTemp = (Character) srcIt.next();
                if (destTemp.equals(srcTemp)) {
                    srcIt.remove();
                    matches++;
                }
            }
        }
        length += srcLength - matches;
        double rate = (double) matches / (double) length * 100;
        BigDecimal b = new BigDecimal(rate);
        int alikePercent = b.setScale(0, BigDecimal.ROUND_HALF_UP).intValue();

        List<Integer> result = new ArrayList<Integer>();
        result.add(0, alikePercent);
        result.add(1, matches);
        result.add(2, length - matches);
        return result;
    }

    public static String unicode2String(String unicode) {

        StringBuffer string = new StringBuffer();

        String[] hex = unicode.split("\\\\u");

        for (int i = 1; i < hex.length; i++) {

            // 转换出每一个代码点
            int data = Integer.parseInt(hex[i], 16);

            // 追加成string
            string.append((char) data);
        }

        return string.toString();
    }

    public static boolean isJsonString(String str) {
        try {
            JSONObject jsonObject = JSONObject.parseObject(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static String replaceHostIp(String url, String replaceIp) {
        String result = null;
        if (StringUtils.isEmpty(url) || StringUtils.isEmpty(replaceIp)) {
            return result;
        }
        String regex = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(url);
        if (m.find()) {
            result = m.replaceFirst(replaceIp);
        }
        return result;
    }
    public static void main(String[] args) {
        String url = "hcdnlive://AYAAAAFXHWUSSQI7OFVWEYKBD467BC3FIEPTZU6TJFAR652UJZRUCH3U2O6D4QI7AQAAAADF4MHC2LQW3I6GKNBOCZX44DIWFYLLOPNHQYXBM?hl_nm=6&hl_cid=ISFFBN7OADIR62JDQMGWHZLLCMHVWF34&hl_slid=c109_ls_zhangjing_smooth_s10&hl_slst=10&hl_cp=3&hl_dl=0&hl_dls=40&hl_dle=50&hl_stapp=live&hl_stid=ls_zhangjing_smooth&hl_sttp=flv&hl_stpr=rtmp&hl_stpt=1935&hl_dp=NB2HI4B2F4XWM3DWNRUXMZJOOZUWIZLPFZUXC2LZNEXGG33NF4&hl_force=0&hl_pltp=0";
        url = url.replaceAll("hl_pltp=\\d{1}", "hl_pltp=1");
        System.out.print(url);
    }

}
